local desc_2v2 = [[
  # 2v2简介

  游戏由两名忠臣和两名反贼进行，胜利目标为击杀所有敌人。

  座位排列可能是 忠-反-反-忠 或者 反-忠-忠-反

  一人死亡后，其队友会摸一张牌。

  第一回合角色摸牌阶段少摸一张牌。四号位多摸一张初始手牌。

  队友手牌可见。

  团队模式：选将前，令随机一名角色确定自己的队友

  可以添加至多两个AI，若AI为队友，则操控它行动。在人类选将后，由人类队友操控AI选将

  如果存在两个AI，则人类必定会选择AI为队友（禁止AI互相成为队友）。如果AI数量大于2则强制平局

  （注：控制AI存在一些BUG）
  当游戏结束后，若你控制AI，退出服务器重进即可还原
  无懈可击询问和AI控制存在BUG，人类和人类控制的AI都有无懈的时候会卡掉线
]]

local new_2v2_getLogic = function()
  local new_2v2_logic = GameLogic:subclass("new_2v2_logic") ---@class GameLogic

  function new_2v2_logic:assignRoles()
    local room = self.room
    local n = #room.players
    local roles = table.random {
      { "loyalist", "rebel", "rebel", "loyalist" },
      { "rebel", "loyalist", "loyalist", "rebel"},
    }


    local humans = table.filter(room.players, function(p) return p.serverplayer:getState() == fk.Player_Online and p.id > 0 end)
    if #humans > 0 then
      local ais = table.filter(room.players, function(p) return p.id < 0 end)
      local human = table.random(humans)
      local friend
      if #ais == 2 then
        friend = table.random(ais)
      elseif #ais < 2 then
        local names = {}
        for i = 1, 4 do
          local p = room.players[i]
          if p ~= human then
            table.insert(names, p._splayer:getScreenName())
          end
        end
        local choice = room:askForChoice(human, names, "new_2v2_mode", "#new_2v2_mode-choosefriend")
        friend = table.find(room.players, function(p) return p._splayer:getScreenName() == choice end)
      end
      if friend then
        local myseat = table.indexOf(room.players, human)
        local p = room.players[5-myseat]
        local fid = table.indexOf(room.players, friend)
        room.players[5-myseat] = friend
        room.players[fid] = p
      end
    end

    for i = 1, n do
      local p = room.players[i]
      p.role = roles[i]
      p.role_shown = true
      room:broadcastProperty(p, "role")
    end

    for i = 1, 4 do
      local me = room.players[i]
      local fri = room.players[5 - i]
      me:addBuddy(fri)
    end
    
    --
    self.start_role = roles[1]
    -- for adjustSeats
    room.players[1].role = "lord"
  end

  function new_2v2_logic:chooseGenerals()
    local room = self.room

    local ais = table.filter(room.players, function(p) return p.id < 0 end)
    if #ais > 0 then
      -- 如果存在AI，防止AI失去控制，应该禁止任何控制类技能
      local blacklist = {"goddiaochan", "n_xxyheaven"}
      for _, g in ipairs(blacklist) do
        table.removeOne(room.general_pile, g)
      end
    end
    if #ais > 2 then
      room:sendLog{type = "#22warningNoAI", toast = true}
      room:gameOver("")
    end

    -- UI限制至多9个框
    local generalNum = math.min(room.settings.generalNum, 9)

    local lord = room:getLord()
    room.current = lord
    lord.role = self.start_role

    local nonlord = room.players
    if #room.general_pile < #nonlord * generalNum then
      room:sendLog{type = "#warningNoGeneral", toast = true}
      room:gameOver("")
    end
    local generals = table.random(room.general_pile, #nonlord * generalNum) ---@class table
    local general_list = {}
    general_list[1] = table.slice(generals, 1, generalNum + 1)
    general_list[2] = table.slice(generals, generalNum + 1, generalNum * 2 + 1)
    general_list[3] = table.slice(generals, generalNum * 2 + 1, generalNum * 3 + 1)
    general_list[4] = table.slice(generals, generalNum * 3 + 1, generalNum * 4 + 1)
    -- 多人控制响应 MiniGame 会导致报错
    room:askForMiniGame(nonlord, "AskForGeneral", "2v2_sel", {
      [nonlord[1].id] = {
        friend_id = nonlord[4].id,
        me = general_list[1], friend = general_list[4],
      },
      [nonlord[2].id] = {
        friend_id = nonlord[3].id,
        me = general_list[2], friend = general_list[3],
      },
      [nonlord[3].id] = {
        friend_id = nonlord[2].id,
        me = general_list[3], friend = general_list[2],
      },
      [nonlord[4].id] = {
        friend_id = nonlord[1].id,
        me = general_list[4], friend = general_list[1],
      },
    })
    -- 请勿控制AI进行2v2选将
    for i = 1, 4 do
      local me = room.players[i]
      local fri = room.players[5 - i]
      if me.id > 0 and fri.id < 0 then
        me:control(fri)
      end
    end

    local chosen = {}
    local choose_again = {} -- 让AI重新选将
    for i, p in ipairs(nonlord) do
      chosen[i] = json.decode(p.client_reply)
      if p.id < 0 then
        table.insert(choose_again, p)
      end
    end
    if #choose_again > 0 then
      for _, p in ipairs(choose_again) do
        local index = table.indexOf(nonlord, p)
        local arg = general_list[index]
        p.request_data = json.encode({ arg, 1 })
        p.default_reply = arg[1]
      end
  
      room:doBroadcastRequest("AskForGeneral", choose_again)
      for _, p in ipairs(choose_again) do
        local index = table.indexOf(nonlord, p)
        if p.reply_ready then
          local general = json.decode(p.client_reply)[1]
          chosen[index] = general
        end
        p.default_reply = ""
      end
    end

    for i, p in ipairs(nonlord) do
      room:findGeneral(chosen[i])
      room:setPlayerGeneral(p, chosen[i], true, true)
    end

    room:askForChooseKingdom(nonlord)
    room:setTag("SkipNormalDeathProcess", true)
    
  end

  return new_2v2_logic
end
local new_2v2_rule = fk.CreateTriggerSkill{
  name = "#new_2v2_rule",
  priority = 0.001,
  refresh_events = {fk.DrawInitialCards, fk.DrawNCards, fk.GameOverJudge, fk.Deathed},
  can_refresh = function(self, event, target, player, data)
    return target == player
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    if event == fk.DrawNCards then
      if player.seat == 1 and player:getMark(self.name) == 0 then
        room:addPlayerMark(player, self.name, 1)
        data.n = data.n - 1
      end
    elseif event == fk.DrawInitialCards then
      if player.seat == 4 then
        data.num = data.num + 1
      end
    elseif event == fk.GameOverJudge then
      local winner = Fk.game_modes[room.settings.gameMode]:getWinner(player)
      if winner ~= "" then
        room:gameOver(winner)
        return true
      end
    else
      for _, p in ipairs(room.alive_players) do
        if p.role == player.role then
          p:drawCards(1, self.name)
        end
      end
    end
  end,
}
Fk:addSkill(new_2v2_rule)

local new_2v2_mode = fk.CreateGameMode{
  name = "new_2v2_mode",
  minPlayer = 4,
  maxPlayer = 4,
  rule = new_2v2_rule,
  logic = new_2v2_getLogic,
  surrender_func = function(self, playedTime)
    local surrenderJudge = { { text = "2v2: left you alive", passed = table.find(Fk:currentRoom().players, function(p)
      return p.role == Self.role and p.dead and p.rest == 0
    end) and true } }
    return surrenderJudge
  end,
  winner_getter = function(self, victim)
    if not victim.surrendered and victim.rest > 0 then
      return ""
    end
    local room = victim.room
    local alive = table.filter(room.players, function(p) ---@type Player[]
      return not p.surrendered and not (p.dead and p.rest == 0)
    end)
    local winner = alive[1].role
    for _, p in ipairs(alive) do
      if p.role ~= winner then
        return ""
      end
    end
    return winner
  end,
}
Fk:loadTranslationTable{
  ["new_2v2_mode"] = "新2v2",
  [":new_2v2_mode"] = desc_2v2,
  ["2v2: left you alive"] = "你所处队伍仅剩你存活",
  ["#new_2v2_mode-choosefriend"] = "请选择你的队友！",
  ["#22warningNoAI"] = "AI数量请勿大于2个！！！",
  ["#warningNoGeneral"] = "武将池数量不足！！！",
  ["#new_2v2_rule"] = "新2v2",
}


return new_2v2_mode
